package cn.schoolwow.workflow.module.task.action.flow.complete.nodeType.gateway.common;

import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.workflow.domain.deploy.WorkFlowDeployJumpFilterCondition;
import cn.schoolwow.workflow.entity.WorkFlowNode;
import cn.schoolwow.workflow.entity.WorkFlowNodeJump;
import cn.schoolwow.workflow.module.task.action.flow.common.GetContextFieldValueValueCommonFlow;
import com.alibaba.fastjson.JSONArray;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class SetMatchWorkFlowNodeJumpListCommonFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        List<WorkFlowNodeJump> workFlowNodeJumpList = flowContext.checkData("workFlowNodeJumpList", List.class);
        String gatewayNodeTypeName = flowContext.checkData("gatewayNodeTypeName", String.class);
        WorkFlowNode gatewayNode = flowContext.checkData("gatewayNode", WorkFlowNode.class);

        List<WorkFlowNodeJump> matchWorkFlowNodeJumpList = new ArrayList<>();
        for(WorkFlowNodeJump workFlowNodeJump:workFlowNodeJumpList){
            JSONArray filterCondition = workFlowNodeJump.getFilterCondition();
            //默认分支
            if(null==filterCondition||filterCondition.isEmpty()){
                matchWorkFlowNodeJumpList.add(workFlowNodeJump);
            }else{
                boolean orCondition = false;
                for(int i=0;i<filterCondition.size();i++){
                    JSONArray filterConditionSubList = filterCondition.getJSONArray(i);
                    List<WorkFlowDeployJumpFilterCondition> workFlowDeployJumpFilterConditions = filterConditionSubList.toJavaList(WorkFlowDeployJumpFilterCondition.class);
                    boolean andCondition = andMatchFilterCondition(workFlowDeployJumpFilterConditions, flowContext);
                    if(andCondition){
                        orCondition = true;
                        break;
                    }
                }
                if(orCondition){
                    matchWorkFlowNodeJumpList.add(workFlowNodeJump);
                }
            }
        }
        if(matchWorkFlowNodeJumpList.isEmpty()){
            throw new IllegalArgumentException(gatewayNodeTypeName+"["+gatewayNode.getName()+"]无满足条件的出口路由");
        }
        flowContext.putCurrentFlowData("matchWorkFlowNodeJumpList", matchWorkFlowNodeJumpList);
    }

    @Override
    public String name() {
        return "设置满足条件的节点列表公共流程";
    }

    private boolean andMatchFilterCondition(List<WorkFlowDeployJumpFilterCondition> workFlowDeployJumpFilterConditions, FlowContext flowContext){
        for(WorkFlowDeployJumpFilterCondition workFlowDeployJumpFilterCondition:workFlowDeployJumpFilterConditions){
            boolean andCondition = false;
            flowContext.startFlow(new GetContextFieldValueValueCommonFlow())
                    .putCurrentCompositeFlowData("fieldName", workFlowDeployJumpFilterCondition.field)
                    .execute();
            Object contextFieldValue = flowContext.checkData("contextFieldValue");
            if("=".equalsIgnoreCase(workFlowDeployJumpFilterCondition.operator)){
                andCondition = contextFieldValue.equals(workFlowDeployJumpFilterCondition.value);
            }else if("包含".equals(workFlowDeployJumpFilterCondition.operator)){
                if(contextFieldValue instanceof Collection){
                    Collection collection = (Collection) contextFieldValue;
                    andCondition = collection.contains(workFlowDeployJumpFilterCondition.value);
                }else if(contextFieldValue.getClass().isArray()){
                    Object[] values = (Object[]) contextFieldValue;
                    andCondition = Arrays.asList(values).contains(workFlowDeployJumpFilterCondition.value);
                }else{
                    throw new IllegalArgumentException("比较方式为[包含],但字段["+workFlowDeployJumpFilterCondition.field+"]的类型为["+contextFieldValue.getClass().getName()+"]");
                }
            }else{
                BigDecimal actualValueBigDecimal = new BigDecimal(contextFieldValue.toString());
                BigDecimal expectBigDecimal = new BigDecimal(workFlowDeployJumpFilterCondition.value.toString());
                switch (workFlowDeployJumpFilterCondition.operator){
                    case ">":{
                        andCondition = actualValueBigDecimal.compareTo(expectBigDecimal)>0;
                    }break;
                    case ">=":{
                        andCondition = actualValueBigDecimal.compareTo(expectBigDecimal)>=0;
                    }break;
                    case "<":{
                        andCondition = actualValueBigDecimal.compareTo(expectBigDecimal)<0;
                    }break;
                    case "<=":{
                        andCondition = actualValueBigDecimal.compareTo(expectBigDecimal)<=0;
                    }break;
                    default:{
                        throw new IllegalArgumentException("暂不支持当前操作符!操作符:"+workFlowDeployJumpFilterCondition.operator);
                    }
                }
            }
            if(!andCondition){
                return false;
            }
        }
        return true;
    }
}
